package com.factory.aiclient.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.factory.aiclient.manager.SocketManager;
import com.factory.aiclient.service.UserDeviceService;
import com.factory.aiclient.util.SpringCtxUtils;
import com.factory.common.bean.UserDevices;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.CrossOrigin;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;

@ServerEndpoint("/aiclient/ws/{deviceId}")
@Controller
@Slf4j
@CrossOrigin
public class WebsocketController {

    private UserDeviceService userDeviceService = SpringCtxUtils.getBean(UserDeviceService.class);

    private RedisTemplate<String, JSONObject> redisTemplate = SpringCtxUtils.getBean(RedisTemplate.class);

    @OnOpen
    public void onOpen(Session session, @PathParam(value = "deviceId") String deviceId) {
        //获取连接的用户
        log.info("加入session:{}", deviceId);
        UserDevices userDevices = userDeviceService.selectById(deviceId);
        if (null == userDevices) {
            log.warn("未知设备连接,{}", deviceId);
            try {
                session.close();
            } catch (IOException e) {
                log.error("关闭session时发生异常,{}", e);
            }
            return;
        } else if (SocketManager.isOnLine(deviceId)) {
            log.warn("该设备已有连接,{}", deviceId);
            Session currentSession = SocketManager.getSession(deviceId);

            log.info("当前设备信息,{},{},{}", currentSession.getRequestURI().getHost()
                    , currentSession.getRequestURI().getUserInfo(), currentSession.getRequestURI().getPath());
            log.info("关闭原有的连接...............................");
            SocketManager.closeSession(currentSession);
        }
        SocketManager.setSession(deviceId, session, userDevices);
    }

    @OnClose
    public void onClose(Session session) {
        log.info("websocket连接关闭,{}", session.getId());
        SocketManager.closeSession(session);
    }

    /**
     * 收到客户端信息,client 回复的消息格式为
     * {"status":True,"message":"开启成功","messageId":"messageId","data":"data"}
     *
     * @param message
     * @param session
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        log.debug("websocket client message => {}, device id => {}", message, SocketManager.getDeviceIdBySession(session.getId()));

        try {
            JSONObject jsonObject = JSON.parseObject(message);
            if (jsonObject.containsKey("heart") && jsonObject.getBoolean("heart")) {
                //            JSONObject heartData = jsonObject.getJSONObject("heartData");
                //            String deviceId = SocketManager.getDeviceIdBySession(session.getId());
                //            if (null != deviceId) {
                //                //将心跳的数据存放到redis数据库里面
                //                String key = String.format("Heartbeat-%s", deviceId);
                //                try {
                //                    ValueOperations<String, JSONObject> stringJSONObjectValueOperations = redisTemplate.opsForValue();
                //                    stringJSONObjectValueOperations.set(key, heartData);
                //                } catch (Exception e) {
                //                    log.error("存放心跳数据异常,{}", e);
                //                }
                //            }
            } else
                SocketManager.setMessage(jsonObject.getString("messageId"), jsonObject.get("data"));

        } catch (Exception e) {
            log.error("on message error,{}", e);
        }
    }

    //错误时调用
    @OnError
    public void onError(Session session, Throwable throwable) {
        log.error("webSocket 错误,{}", throwable);
        SocketManager.closeSession(session);
    }

}